using Game.Networking.Client;
using Game.Networking.Server;
using Game.UI;
using SMGCore;
using UnityEngine;

namespace Game {
	public class SpectatorCamera : MonoSingleton<SpectatorCamera> {
		public bool FollowTarget = false;
		public bool ConfineCameraPosToOtherTransform = false;
		public float ConfineDistance = 50f;
		public float FocusDistance = 10f;
		public Transform ConfineTarget;

		Vector3 _prevTargetPos;
		bool _prevTickHasTarget = false;

		private void Update() {
			var ui = UIHolder.Instance;
			if ( ui.HasFocus ) {
				return;
			}
			if ( Input.GetKeyDown(KeyCode.F) ) {
				CenterToTarget();
			}
			if ( Input.GetKeyDown(KeyCode.C) ) {
				ConfineCameraPosToOtherTransform = !ConfineCameraPosToOtherTransform;
			}
			if ( Input.GetKeyDown(KeyCode.R) ) {
				FollowTarget = !FollowTarget;
			}
		}

		private void LateUpdate() {
			if ( ConfineCameraPosToOtherTransform && ConfineTarget ) {
				float distance = Vector3.Distance(transform.position, ConfineTarget.position);
				if ( distance > ConfineDistance ) {
					var direction = Vector3.Normalize(ConfineTarget.position - transform.position);
					transform.position = ConfineTarget.position + direction * ConfineDistance;
				}
			}
			if ( ConfineTarget ) {
				if ( _prevTickHasTarget && FollowTarget ) {
					var delta = ConfineTarget.position - _prevTargetPos;
					transform.position += delta;
				}
				_prevTargetPos = ConfineTarget.position;
				_prevTickHasTarget = true;
			} else {
				_prevTickHasTarget = false;
				_prevTargetPos = Vector3.zero;
			}
		}

		public void CenterToTarget() {
			if ( !ConfineTarget ) {
				if ( GameManager.Instance.IsServer) {
					var id = ServerDebugController.Instance.DebugUnitWatcher?.Target?.Data?.AttachedEntity ?? 0;
					var e = ServerEntityController.Instance.GetEntityById(id);
					if ( e != null ) {
						var s = (ShipCore)e;
						if ( s != null ) {
							ConfineTarget = s.transform;
						}
					}
				} else {
					var id = ClientScriptingController.Instance.GetAttachedEntityId();
					var e = ClientEntityController.Instance.GetEntityById(id);
					if ( e != null ) {
						var s = (ShipCore)e;
						if ( s != null ) {
							ConfineTarget = s.transform;
						}
					}
				}
			}

			if ( !ConfineTarget) {
				return;
			}
			var direction = Vector3.Normalize(ConfineTarget.position - transform.position);
			transform.position = ConfineTarget.position + direction * FocusDistance;

			transform.LookAt(ConfineTarget);
		}
	}
}

